package com.starryx.sim.mvc.net.handler;


import com.fasterxml.jackson.core.type.TypeReference;
import com.starryx.sim.mvc.controller.ControllerManager;
import com.starryx.sim.mvc.controller.RequestMappingWrapper;
import com.starryx.sim.mvc.net.handler.task.HandleTask;
import com.starryx.sim.mvc.util.JsonUtil;
import com.starryx.sim.mvc.util.SpringContextUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import org.apache.commons.codec.CharEncoding;
import org.apache.commons.codec.Charsets;

import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public abstract class AbstractRequestHandler implements RequestHandler {

	// todo：到时候可以设置为多线程，但要检查其他地方有没有线程安全问题
	private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

	@Override
	public void handle(FullHttpRequest fullHttpRequest, ChannelHandlerContext ctx) {
		ControllerManager controllerManager = SpringContextUtil.getBean(ControllerManager.class);
		String json = getParam(fullHttpRequest);
		RequestMappingWrapper requestMappingWrapper = new RequestMappingWrapper(getUri(fullHttpRequest), fullHttpRequest.method());
		Object param;
		if (controllerManager.checkRequestParam(requestMappingWrapper)) {
			param = JsonUtil.toObject(json, new TypeReference<Map<String, Object>>() {
			});
		} else {
			param = JsonUtil.toObject(json, controllerManager.findParamType(requestMappingWrapper));
		}
		if (param == null) {
			throw new IllegalArgumentException("请求参数与处理方法的参数不匹配");
		}
		executor.execute(new HandleTask(requestMappingWrapper, param, fullHttpRequest, ctx));
	}

	protected abstract String getParam(FullHttpRequest fullHttpRequest);

	private String getUri(FullHttpRequest fullHttpRequest) {
		return new QueryStringDecoder(fullHttpRequest.uri(), Charsets.toCharset(CharEncoding.UTF_8)).path();
	}

}
